package com.cantor.example.test;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import lombok.Data;
import lombok.experimental.Accessors;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.IntUnaryOperator;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class WeightRandom {

    // 测试加权随机负载均衡算法
    @Test
    public void testWeightRandom() {
        List<WeightObj> weightObjs = Arrays.asList(
                new WeightObj().setData("HUAWEI").setWeight(5),
                new WeightObj().setData("XIAOMI").setWeight(3),
                new WeightObj().setData("MEIZU").setWeight(1)
        );
        for (int i = 0; i < 9; i++) {
            System.out.println(loadGet(weightObjs));
        }

    }

    WeightObj[] sortedArr;

    String loadGet(List<WeightObj> factors) {
        if(ArrayUtil.isEmpty(sortedArr)){
            // 1. 先进行排序
            Collections.sort(factors, (p, v) -> v.getWeight()-p.getWeight());
            sortedArr = ((WeightObj[]) factors.toArray());
        }
        // 2. 综合
        int total = factors.stream().mapToInt(o -> o.getWeight()).sum();
        // 3.随机offset
        int offset = RandomUtil.randomInt(total);
        // 4. 命中
        for (int i = 0; i < sortedArr.length; i++) {
            WeightObj candidate = sortedArr[i];
            if (offset < candidate.getWeight()){
                return candidate.getData();
            }
            offset -= candidate.getWeight();
        }
        return null;
    }

    @Data
    @Accessors(chain = true)
    class WeightObj {
        private String data;
        private int weight = 1;
    }

}
